﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using Emerald;
using RunnableProject.DrawableObjects;
using Action = Emerald.Action;
using Board = RunnableProject.DrawableObjects.Board;

namespace RunnableProject
{
    public partial class MainForm : Form
    {
        private Game game;
        private Board board;
        private BoardPoint selectedBoardPoint;
        private Tile selectedPiece;
        private bool MouseIsActive, GameIsOver = true;

        public MainForm()
        {
            InitializeComponent();
        }

        private void panel1_Paint(object sender, PaintEventArgs e)
        {

            int gridX = panel1.Width / Globals.TileSize;
            for (int i = 0; i <= gridX; i++)
            {
                e.Graphics.DrawLine(new Pen(Color.Gray), new Point(i * Globals.TileSize, 0), new Point(i * Globals.TileSize, panel1.Height));
                if (i > 0)
                    e.Graphics.DrawLine(new Pen(Color.LightGray), new Point(i * Globals.TileSize - 1, 0), new Point(i * Globals.TileSize - 1, panel1.Height));
            }
            int gridY = panel1.Height / Globals.TileSize;
            for (int i = 0; i <= gridY; i++)
            {
                e.Graphics.DrawLine(new Pen(Color.Gray), new Point(0, i * Globals.TileSize), new Point(panel1.Width, i * Globals.TileSize));
                if (i > 0)
                    e.Graphics.DrawLine(new Pen(Color.LightGray), new Point(0, i * Globals.TileSize - 1), new Point(panel1.Width, i * Globals.TileSize - 1));
            }
            //panel1.Height / Globals.TileSize;
            if (board != null)
            {
                e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                if (selectedPiece != null)
                {
                    board.Draw(e.Graphics, selectedPiece.Location);
                }
                else
                {
                    board.Draw(e.Graphics, default(BoardPoint));
                }
                e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.Default;
            }
        }

        private void debugInformationToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Globals.Debug = debugToolStripMenuItem.Checked;
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            OpenNewGameDialog();
        }

        private void setPlayerInStatus()
        {
            if (GameIsOver)
                toolStripStatusLabel1.Text = "" + game.ColorToPlay.Opposite() + " player won the game.";
            else
                toolStripStatusLabel1.Text = game.ColorToPlay.ToString() + " player to play.";
        }
        private void setCoordinatesInStatus(int x, int y)
        {
            if (GameIsOver)
                toolStripStatusLabel2.Text = x + ", " + y;
            else
                toolStripStatusLabel2.Text = "";
        }
        public void setStatus(int x, int y)
        {
            setPlayerInStatus();
            setCoordinatesInStatus(x, y);
        }

        private void panel1_MouseDown(object sender, MouseEventArgs e)
        {
            if (MouseIsActive && !GameIsOver)
            {
                if (board != null)
                {
                    if (e.Button == MouseButtons.Left)
                    {
                        // left click
                        Action a = null;

                        byte xIndex = (byte)(e.X / Globals.TileSize);
                        byte yIndex = (byte)(e.Y / Globals.TileSize);
                        BoardPoint bp = new BoardPoint(xIndex, yIndex);
                        Tile t = board.board.BoardArray[bp];

                        bool b = false;

                        // not enough pieces to move, place new
                        if (board.board.BoardArray.Pieces.Count(p => p != null) < 12)
                        {
                            a = new Action(bp, game.ColorToPlay);
                            b = game.GameState.PerformAction(a);
                        }
                        // move pieces, enough pieces.
                        else
                        {
                            // is there a tile w/ piece selected
                            if (selectedPiece != null)
                            {
                                if (t == null)
                                {
                                    selectedBoardPoint = bp;
                                }
                                else
                                {
                                    if (t.Piece == null)
                                    {

                                        if (selectedBoardPoint.Set)
                                        {
                                            a = new Action(t.Location, selectedPiece.Location, selectedBoardPoint);
                                            b = game.GameState.PerformAction(a);
                                            

                                            selectedPiece = null;
                                            selectedBoardPoint = default(BoardPoint);
                                        }
                                        else
                                        {
                                            a = new Action(selectedPiece.Location, t.Location);
                                            b = game.GameState.PerformAction(a);

                                            selectedPiece = null;
                                        }
                                    }
                                }
                            }

                            else
                            {
                                if (t != null && t.Piece != null && t.Piece.Color == game.ColorToPlay)
                                    selectedPiece = t;
                            }
                        }


                        //if(a.HasValue)
                        //b=game.GameState.PerformAction(a.Value);

                        panel1.Invalidate();
                    }
                    setStatus((e.X / Globals.TileSize), (e.Y / Globals.TileSize));
                }
            }
        }

        private void showWindowInformationToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MessageBox.Show(string.Format("Window: {0}\r\nPanel: {1}\r\nGlobals: {2}", this.Size, panel1.Size, new Size(Globals.BoardWidth, Globals.BoardHeight)));
        }

        private void newGameToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenNewGameDialog();
            panel1.Invalidate();
        }

        public void OpenNewGameDialog()
        {
            NewGameDialog ngd = new NewGameDialog();
            ngd.ShowDialog();
            if (ngd.DialogResult == DialogResult.OK)
            {
                game = new Game(ngd.WhitePlayer, ngd.RedPlayer, ngd.StartingPlayer);
                board = new Board(game);
                game.PlayerChanged += game_PlayerChanged;
                game.GameEnded += game_GameEnded;
                GameIsOver = false;
                setPlayerInStatus();
                // Human player is to start?
                if (((ngd.WhitePlayer is HumanPlayer) && ngd.WhitePlayer.Color == ngd.StartingPlayer) ||
                    ((ngd.RedPlayer is HumanPlayer) && ((HumanPlayer)ngd.RedPlayer).Color == ngd.StartingPlayer))
                {
                    MouseIsActive = true;
                }
                // AI needs to start
                else
                {
                    MouseIsActive = false;
                    AI p = (AI)game.PlayerToPlay;
                    game.GameState.PerformAction(new Action(p.DoTurn(game.GameState.DataString)));
                }
            }
        }

        void game_PlayerChanged(object sender, EColor newPlayer)
        {
            if (GameIsOver)
                return;

            panel1.Invalidate();

            // if player is not human, ask the engine for the next move.
            // else activate mouse.
            if (!(game.PlayerToPlay is HumanPlayer))
            {
                MouseIsActive = false;
                AI p = (AI)game.PlayerToPlay;
                game.GameState.PerformAction(new Action(p.DoTurn(game.GameState.DataString)));
            }
            else
            {
                MouseIsActive = true;
            }
        }

        void game_GameEnded(object sender, EColor winningPlayer)
        {
            GameIsOver = true;
            DialogResult dr = MessageBox.Show(string.Format("The {0} player won.\r\nDo you want to play another game?", winningPlayer.ToString().ToLowerInvariant()), "Game over", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

            if (dr.Equals(DialogResult.Yes))
            {
                OpenNewGameDialog();
            }
        }

        private void panel1_MouseUp(object sender, MouseEventArgs e)
        {
        }
    }

}
